/*
 * Algorithms.h
 *
 *  Created on: 22 Aug 2011
 *      Author: Allan
 */

#ifndef ALGORITHMS_H_
#define ALGORITHMS_H_

// C++ includes
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

// Boost includes
#include <boost/foreach.hpp>

const unsigned 
IndexOf(const string& s, const vector<string>& svec);

const bool 
IsContained(const string& s, const vector<string>& svec);

template<typename T> const vector<T>
Union(const vector<T>& vecA, const vector<T>& vecB);

template<typename T> const vector<T>
Intersection(const vector<T>& vecA, const vector<T>& vecB);

template<typename T> const vector<T>
Difference(const vector<T>& vecA, const vector<T>& vecB);

template<typename T> const vector<T>
Unique(const vector<T>& vec);


//==========================================================================//
// Implementation
//==========================================================================//

template<typename T> 
const vector<T> Union(const vector<T>& vecA, const vector<T>& vecB)
{
	set<T> set;
	
	set.insert(vecA.begin(), vecA.end());
	set.insert(vecB.begin(), vecB.end());
	
	return vector<T>(set.begin(), set.end());
}

template<typename T> 
const vector<T> Intersection(const vector<T>& vecA, const vector<T>& vecB)
{
	vector<T> intersection;
	
	BOOST_FOREACH(auto s, vecA)
		if(IsContained(s, vecB))
			intersection.push_back(s);
	
	return intersection;
}

template<typename T> 
const vector<T> Difference(const vector<T>& vecA, const vector<T>& vecB)
{
	vector<T> difference;
	
	BOOST_FOREACH(auto s, vecA)
		if(!IsContained(s, vecB))
			difference.push_back(s);
	
	return difference;
}

template<typename T> 
const vector<T> Unique(const vector<T>& vec)
{
	set<T> set(vec.begin(), vec.end());
	
	return vector<T>(set.begin(), set.end());
}

#endif /* ALGORITHMS_H_ */
